package br.com.intelsys.basics.spring;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.validator.GenericValidator;

public class CookieMap implements Map<String, Cookie> {

	private final Map<String, Cookie> cookieMap;
	private final Cookie[] cookies;
	private final HttpServletResponse resp;

	CookieMap(HttpServletResponse resp, Cookie[] cookies) {
		this.resp = resp;
		cookieMap = new HashMap<String, Cookie>(cookies == null ? 0 : cookies.length);
		if (cookies != null) {
			this.cookies = cookies;
		} else {
			this.cookies = new Cookie[0];
		}
		loadMap();
	}

	private void loadMap() {
		for (Cookie cookie : cookies) {
			cookieMap.put(cookie.getName(), cookie);
		}
	}

	public void clear() {
		cookieMap.clear();
		for (Cookie c : cookies) {
			c.setMaxAge(0);
			c.setValue(null);
			resp.addCookie(c);
		}
	}

	@Override
	public boolean containsKey(Object key) {
		return cookieMap.containsKey(key);
	}

	@Override
	public boolean containsValue(Object cookie) {
		return cookieMap.containsKey(cookie);
	}

	public Set<java.util.Map.Entry<String, Cookie>> entrySet() {
		return cookieMap.entrySet();
	}

	@Override
	public Cookie get(Object name) {
		return cookieMap.get(name);
	}

	@Override
	public boolean isEmpty() {
		return cookieMap.isEmpty();
	}

	@Override
	public Set<String> keySet() {
		return cookieMap.keySet();
	}

	public Cookie put(String name, String value, int expiry, String domainPattern, String pathUri) {
		Cookie cookie = new Cookie(name, value);
		cookie.setMaxAge(expiry);
		cookie.setDomain(domainPattern);
		cookie.setPath(pathUri);
		return put(cookie.getValue(), cookie);
	}

	public Cookie put(String name, String value, int expiry, String domainPattern) {
		Cookie cookie = new Cookie(name, value);
		cookie.setMaxAge(expiry);
		cookie.setDomain(domainPattern);
		return put(cookie.getValue(), cookie);
	}

	public Cookie put(String name, String value, int expiry) {
		Cookie cookie = new Cookie(name, value);
		cookie.setMaxAge(expiry);
		return put(cookie.getValue(), cookie);
	}

	public Cookie put(String name, String value) {
		Cookie cookie = new Cookie(name, value);
		return put(cookie.getValue(), cookie);
	}

	public Cookie put(Cookie cookie) {
		return put(cookie.getValue(), cookie);
	}

	@Override
	public Cookie put(String name, Cookie cookie) {
		if (GenericValidator.isBlankOrNull(cookie.getPath())) {
			cookie.setPath("/");
		}
		resp.addCookie(cookie);
		return cookieMap.put(name, cookie);
	}

	@Override
	public void putAll(Map<? extends String, ? extends Cookie> map) {
		Set<?> entrySet = map.entrySet();
		for (Object o : entrySet) {
			@SuppressWarnings("unchecked")
			Entry<String, Cookie> e = (Entry<String, Cookie>) o;
			put(e.getKey(), e.getValue());
		}
	}

	@Override
	public Cookie remove(Object name) {
		Cookie c = cookieMap.get(name);
		if (c != null) {
			c.setMaxAge(0);
			c.setValue(null);
			resp.addCookie(c);
		}
		return c;
	}

	public int size() {
		return cookieMap.size();
	}

	public Collection<Cookie> values() {
		return cookieMap.values();
	}

}
